package com.sc.nft.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sc.nft.dao.*;
import com.sc.nft.entity.*;
import com.sc.nft.entity.dto.GetUserCityServerCentreListDTO;
import com.sc.nft.entity.dto.GetUserCityServerCentrePageDTO;
import com.sc.nft.entity.dto.UserCityServerCentreDTO;
import com.sc.nft.entity.vo.*;
import com.sc.nft.enums.*;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.mapper.UserCityServerCentreMapper;
import com.sc.nft.mapper.UserCollectionMapper;
import com.sc.nft.mapper.UserPerformanceMapper;
import com.sc.nft.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@Service
public class UserCityServerCentreServiceImpl implements UserCityServerCentreService {

    private final UserCityServerCentreDao userCityServerCentreDao;

    private final UserCityServerCentreMapper mapper;

    private final UserPerformanceDao performanceDao;

    private final UserPerformanceMapper userPerformanceMapper;

    private final UserWalletDao userWalletDao;
    private final UserWalletDetailDao userWalletDetailDao;
    private final ExpenditureRecordDao expenditureRecordDao;

    private final UserInfoDao userInfoDao;

    private final UserInterestsRedPacketService userInterestsRedPacketService;

    private final ServiceCenterAuditDao serviceCenterAuditDao;

    private final UserWorkRoomDao userWorkRoomDao;

    private final CityDataDao cityDataDao;

    private final UserPerformanceService userPerformanceService;

    private final UserMarketValueService userMarketValueService;

    private final ApplicationRequirementService applicationRequirementService;

    private final ApplicationRequirementSmsService applicationRequirementSmsService;
    private final ServiceCenterAuditService serviceCenterAuditService;
    private final UserCityServerCentreDownDao userCityServerCentreDownDao;


    @Override
    public List<GetUserCityServerCentreListVO> getUserCityServerCentreList(GetUserCityServerCentreListDTO getUserCityServerCentreListDTO) {
        return userCityServerCentreDao.getUserCityServerCentreList(getUserCityServerCentreListDTO);
    }



    @Override
    public Page<GetUserCityServerCentrePageVO> selectPage(GetUserCityServerCentrePageDTO getUserCityServerCentreListDTO) {
        return userCityServerCentreDao.selectPage(getUserCityServerCentreListDTO);
    }



    /**
     * 根据userId查询对象
     *
     * @param userId
     * @return
     */
    @Override
    public UserCityServerCentre selectByUserId(Long userId) {
        return userCityServerCentreDao.selectByUserId(userId);
    }

    /**
     * 根据userId修改用户省市区
     *
     * @param userCityServerCentre
     * @return
     */
    @Override
    public Boolean byUserIdSaveModel(UserCityServerCentre userCityServerCentre) {
        if (userCityServerCentre.getProvince() != null) {
            return userCityServerCentreDao.byUserIdSaveModel(userCityServerCentre);
        }
        throw new GlobalRunTimeException("省级不允许为空");
    }

    /**
     * 新增用户城市服务中心
     *
     * @return
     */
    @Override
    public Boolean saveUserCityServerCentre(UserCityServerCentreDTO userCityServerCentreDTO) {
        String userTel = userCityServerCentreDTO.getUserTel();
        UserInfo oneByUserTel = userInfoDao.getOneByUserTel(userTel);
        if (BeanUtil.isEmpty(oneByUserTel)) {
            throw new GlobalRunTimeException("该手机号未注册");
        }
        UserCityServerCentre verification = userCityServerCentreDao.selectByUserId(oneByUserTel.getId());
        if (BeanUtil.isNotEmpty(verification)) {
            throw new GlobalRunTimeException("该用户已经是服务中心");
        }

        UserWorkRoom userWorkRoom = userWorkRoomDao.selectByUserId(oneByUserTel.getId());
        if (BeanUtil.isNotEmpty(userWorkRoom)) {
            throw new GlobalRunTimeException("社区网点无法设置为城市服务中心,请取消社区网点再试");
        }

        UserCityServerCentre userCityServerCentre = BeanUtil.copyProperties(userCityServerCentreDTO, UserCityServerCentre.class);
        userCityServerCentre.setUserId(oneByUserTel.getId());
        userCityServerCentre.insert();
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean cancelUserCityServerCentre(Long id) {
        UserCityServerCentre userCityServerCentre = userCityServerCentreDao.getById(id);
        Assert.notNull(userCityServerCentre,()->new GlobalRunTimeException("未找到服务中心"));
        // 删除服务中心的申请记录.
        serviceCenterAuditDao.cancelCommunityOutletsRecord(userCityServerCentre.getUserId(),2);
        return userCityServerCentre.deleteById();
    }





 



    @Override
    public void calComplianceData() {
        cityDataDao.clearData();
        List<UserCityServerCentre> list = userCityServerCentreDao.list();
        List<CityData> datas = Lists.newArrayList();
        String date = DateUtil.offsetMonth(DateTime.now(),-1).toString("yyyyMMdd");
        Map<Long,List<Long>> downCity = Maps.newHashMap();
        Map<Long,List<Long>> downWork = Maps.newHashMap();
        for (UserCityServerCentre userCityServerCentre : list) {
            downCity.put(userCityServerCentre.getUserId(),Lists.newArrayList());
            downWork.put(userCityServerCentre.getUserId(),Lists.newArrayList());
            CityData cityData = new CityData();
            cityData.setUserId(userCityServerCentre.getUserId());
            cityData.setNextCityCount(0);
            cityData.setPerformance(performanceDao.getCenterSumTermPerformance(userCityServerCentre.getUserId(),date));

            datas.add(cityData);
        }
        for (CityData data : datas) {
            Long cityId=mapper.getNearServiceCity(data.getUserId());
            if(ObjectUtil.isNotNull(cityId)){
                downCity.get(cityId).add(data.getUserId());
            }
        }


        List<UserWorkRoom> list1 = userWorkRoomDao.list();
        for (UserWorkRoom userWorkRoom : list1) {
            Long cityId=mapper.getNearServiceCity(userWorkRoom.getUserId());
            if(ObjectUtil.isNotNull(cityId)){
                downWork.get(cityId).add(userWorkRoom.getUserId());
            }
        }

        for (CityData data : datas) {
            StringBuffer remark = new StringBuffer();
            StringBuffer remark1 = new StringBuffer();
            StringBuffer remark2 = new StringBuffer();
            remark.append("下级服务中心：");
            for (Long aLong : downCity.get(data.getUserId())) {
                remark.append(aLong+" ");
            }
            data.setNextCityCount(downCity.get(data.getUserId()).size());
            data.setWorkCount(downWork.get(data.getUserId()).size());
            data.setValidCount(userPerformanceMapper.getValidUserCount(data.getUserId(),downCity.get(data.getUserId()),date));
            List<UserInfo> listByRecommendId = userInfoDao.getListByRecommendId(data.getUserId());
            BigDecimal max = BigDecimal.ZERO;
            BigDecimal sum = BigDecimal.ZERO;
            Integer maxCount = 0;
            Integer sumCount = 0;
            remark1.append("小区业绩：");
            remark2.append("小区有效用户：");
            for (UserInfo userInfo : listByRecommendId) {
                BigDecimal centerSumTermPerformance = performanceDao.getCenterSumTermPerformance(userInfo.getId(), date);
                Integer validUserCount = userPerformanceMapper.getValidUserCount(userInfo.getId(), mapper.getNextServiceCity(userInfo.getId()), date);
                remark2.append(userInfo.getId()+"有效用户"+validUserCount+" ");
                remark1.append(userInfo.getId()+"业绩"+centerSumTermPerformance+" ");
                if(NumberUtil.isGreater(centerSumTermPerformance,max)){
                    max= centerSumTermPerformance;
                    maxCount=validUserCount;
                }
                sum = sum.add(centerSumTermPerformance);
                sumCount+=validUserCount;
            }
            data.setBeizhu(remark.append(remark1).append(remark2).toString());
            data.setSmallPerformance(sum.subtract(max));
            data.setSmallValidCount(sumCount-maxCount);

        }

        for (CityData data : datas) {
            if(data.getNextCityCount()>=2  ){
                data.setRemark("培育服务中心达标");
            }else if (NumberUtil.isGreaterOrEqual(data.getPerformance(),BigDecimal.valueOf(5000000))&&(data.getValidCount()>=300 || data.getWorkCount()>=12)){
                data.setRemark("业绩达标");
            }else if (NumberUtil.isGreaterOrEqual(data.getSmallPerformance(),BigDecimal.valueOf(1200000))&&(data.getSmallValidCount()>=120 || data.getWorkCount()>=12)){
                data.setRemark("小区业绩达标");
            }else if (NumberUtil.isGreaterOrEqual(data.getSmallPerformance(),BigDecimal.valueOf(800000))&& data.getSmallValidCount()>=48){
                data.setRemark("考察期，截止到"+DateUtil.offsetMonth(DateTime.now(),1).toString("yyyyMMdd"));
            }else{
                data.setRemark("不合格");
            }
            data.insert();
        }


    }

    @Override
    public List<CityServerCentreExportVO> centerServerExport() {
        List<CityServerCentreExportVO> result = userCityServerCentreDao.centerServerExport();
        for (CityServerCentreExportVO vo : result) {
            UserInfo userInfo = userInfoDao.getOneByUserTel(vo.getUserTel());
            BigDecimal teamPerformanceThisMonth = userPerformanceService.getPerformanceNearDate(userInfo.getId(), 30,true);
            Integer byListUserIdCountValid = userInfoDao.getByListUserIdCountValid(userInfo.getId(),true);
            BigDecimal teamCost = userMarketValueService.getEcologyMarketValue(userInfo.getId());
            vo.setTeamCost(teamCost);
            vo.setValidatedUser(byListUserIdCountValid);
            vo.setTeamPerformanceThisMonth(teamPerformanceThisMonth);
            vo.setTypeName("城市服务中心");
        }
        return result;
    }
    /**
     * 获取城市服务中心排除白名单的列表
     * @return
     */
    @Override
    public List<UserWorkRoomExcludeWhiteListRankVO> getUserCityServerCentreExcludeWhiteListRank() {
        return userCityServerCentreDao.getUserCityServerCentreExcludeWhiteListRank();
    }
    /**
     * 获取城市服务中心总数
     * @return
     */
    @Override
    public Integer getCount() {
        return userCityServerCentreDao.getCount();
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void downgrade(UserCityServerCentre userCityServerCentre, Long assessId) {
        if (BeanUtil.isEmpty(userCityServerCentre)) {
            return;
        }
        // 获取用户数据
        UserInfo user = userInfoDao.getById(userCityServerCentre.getUserId());
        WebApplicationRequirementVO webApplicationRequirementVO = applicationRequirementService.webApplicationRequirementUserVO(user, 2);
        //  根据方法返回的结果,判断是否满足条件
        Boolean satisfy = webApplicationRequirementVO.whetherThereAreConditionsForPassing();
        if (satisfy) {
            WorkCityServerAssessDetailLog workCityServerAssessDetailLog = new WorkCityServerAssessDetailLog();
            workCityServerAssessDetailLog.setUserId(user.getId());
            workCityServerAssessDetailLog.setAssessId(assessId);
            workCityServerAssessDetailLog.setResult(JSONObject.toJSONString(webApplicationRequirementVO));
            workCityServerAssessDetailLog.insert();
        } else {
            // 降级,并且记录降级的数据
            WorkCityServerAssessDetailLog workCityServerAssessDetailLog = new WorkCityServerAssessDetailLog();
            workCityServerAssessDetailLog.setUserId(user.getId());
            workCityServerAssessDetailLog.setAssessId(assessId);
            workCityServerAssessDetailLog.setType(WorkCityServerAssessDetailEnum.DOWN);
            workCityServerAssessDetailLog.setResult(JSONObject.toJSONString(webApplicationRequirementVO));
            workCityServerAssessDetailLog.insert();
            // 把该条数据干掉,但是干掉之前,要把他的数据记录降级表中,作为下次进行升级查询数据.
            userCityServerCentre.deleteById();
            // 设置为空是为了让UserCityServerCentreDown的id自增
            userCityServerCentre.setId(null);
            UserCityServerCentreDown userCityServerCentreDown = BeanUtil.copyProperties(userCityServerCentre, UserCityServerCentreDown.class);
            userCityServerCentreDown.setRemark("服务中心降级下来的用户");
            userCityServerCentreDown.insert();
            // 短信通知
            applicationRequirementSmsService.sendSms(user.getUserTel(),WorkCityServerAssessDetailEnum.DOWN);
            UserWorkRoom exist = userWorkRoomDao.selectByUserId(user.getId());
            if (BeanUtil.isNotEmpty(exist)) {
                return;
            }
            // 给用户新增一条,服务中心的数据
            UserWorkRoom userWorkRoom = new UserWorkRoom();
            userWorkRoom.setWorkName(StrUtil.format("名字{}",user.getId()));
            userWorkRoom.setUserId(user.getId());
            userWorkRoom.insert();
            serviceCenterAuditService.deleteByUserIdAndType(user.getId(),2);
        }
    }

    @Override
    public void preDowngrade(UserCityServerCentre userCityServerCentre) {
        if (BeanUtil.isEmpty(userCityServerCentre)) {
            return;
        }
        // 获取用户数据
        UserInfo user = userInfoDao.getById(userCityServerCentre.getUserId());
        WebApplicationRequirementVO webApplicationRequirementVO = applicationRequirementService.webApplicationRequirementUserVO(user, 2);
        //  根据方法返回的结果,判断是否满足条件
        Boolean satisfy = webApplicationRequirementVO.whetherThereAreConditionsForPassing();
        if (satisfy) {
            WorkCityServerPreAssess workCityServerPreAssess = new WorkCityServerPreAssess();
            workCityServerPreAssess.setUserId(user.getId());
            workCityServerPreAssess.setType(ApplicationRequirementUpOrDownEnum.CITY);
            workCityServerPreAssess.setAssessType(WorkCityServerPreAssessTypeEnum.NO_UP_AND_NO_DOWN);
            workCityServerPreAssess.setResult(JSONObject.toJSONString(webApplicationRequirementVO));
            workCityServerPreAssess.setPreAssessDate(new Date());
            workCityServerPreAssess.insert();
        } else {
            // 降级,并且记录降级的数据
            WorkCityServerPreAssess workCityServerPreAssess = new WorkCityServerPreAssess();
            workCityServerPreAssess.setUserId(user.getId());
            workCityServerPreAssess.setType(ApplicationRequirementUpOrDownEnum.CITY);
            workCityServerPreAssess.setAssessType(WorkCityServerPreAssessTypeEnum.DOWN);
            workCityServerPreAssess.setResult(JSONObject.toJSONString(webApplicationRequirementVO));
            workCityServerPreAssess.setPreAssessDate(new Date());
            workCityServerPreAssess.insert();
            // 短信通知
            applicationRequirementSmsService.sendPreSms(user.getUserTel(),ApplicationRequirementUpOrDownEnum.CITY);
        }
    }

    @Override
    public void upgrade(UserWorkRoomExcludeWhiteListRankVO userWorkRoomExcludeWhiteListRankVO, Long assessId) {
        // 获取用户数据
        UserCityServerCentreDown userCityServerCentreDown = userCityServerCentreDownDao.getUserId(userWorkRoomExcludeWhiteListRankVO.getUserId());
        UserInfo user = userInfoDao.getById(userCityServerCentreDown.getUserId());
        WebApplicationRequirementVO webApplicationRequirementVO = applicationRequirementService.webApplicationRequirementUserVO(user, 2);
        //  根据方法返回的结果,判断是否满足条件
        Boolean satisfy = webApplicationRequirementVO.whetherThereAreConditionsForPassing();
        if (satisfy) {
            // 在升级的时候先判定这个用户是不是已经是社区网点,如果是的话,要干掉这个社区网点.否则给两次奖励,这个钱不能给出去
            UserWorkRoom userWorkRoom = userWorkRoomDao.selectByUserId(user.getId());
            // 如果存在的话直接返回执行下一条
            if (BeanUtil.isNotEmpty(userWorkRoom)) {
                userWorkRoom.deleteById();
            }

            // 判定他是不是城市服务中心
            UserCityServerCentre userCityServerCentre = userCityServerCentreDao.selectByUserId(user.getId());
            // 是城市服务中心,直接干掉这条数据,不在升级
            if (BeanUtil.isNotEmpty(userCityServerCentre)) {
                // 哪怕删掉这一条数据也先修改一下备注,使用手动删除方式干掉这条数据
                userCityServerCentreDown.setRemark("用户已经是城市服务中心了,不在对他的社区网点进行升级");
                userCityServerCentreDown.updateById();
                userCityServerCentreDown.deleteById();
                return;
            }

            // 新建一条城市服务中心的数据
            UserCityServerCentre addUserCitySeverCentre = new UserCityServerCentre();
            addUserCitySeverCentre.setUserId(user.getId());
            addUserCitySeverCentre.setProvince(userCityServerCentreDown.getProvince());
            addUserCitySeverCentre.setCity(userCityServerCentreDown.getCity());
            addUserCitySeverCentre.setDistrict(userCityServerCentreDown.getDistrict());
            addUserCitySeverCentre.insert();
            // 短信通知
            applicationRequirementSmsService.sendSms(user.getUserTel(),WorkCityServerAssessDetailEnum.UP);
            //  升级记录
            WorkCityServerAssessDetailLog workCityServerAssessDetailLog = new WorkCityServerAssessDetailLog();
            workCityServerAssessDetailLog.setUserId(user.getId());
            workCityServerAssessDetailLog.setType(WorkCityServerAssessDetailEnum.UP);
            workCityServerAssessDetailLog.setAssessId(assessId);
            workCityServerAssessDetailLog.setResult(JSONObject.toJSONString(webApplicationRequirementVO));
            workCityServerAssessDetailLog.insert();
            userCityServerCentreDown.deleteById();
        }else {
            // 记录一条未升级的数据
            WorkCityServerAssessDetailLog workCityServerAssessDetailLog = new WorkCityServerAssessDetailLog();
            workCityServerAssessDetailLog.setUserId(user.getId());
            workCityServerAssessDetailLog.setAssessId(assessId);
            workCityServerAssessDetailLog.setResult(JSONObject.toJSONString(webApplicationRequirementVO));
            workCityServerAssessDetailLog.insert();
        }
    }
}
